ident = '$Id: newsletter_ui.py 119 2006-06-19 18:30:47Z trevor $'

import wx, wx.gizmos, rex, common, images, re, publications
#import newsletter_components
from xml.dom	 import minidom

# Sort BY and Find By
BY_ID		= 0
BY_NAME		= 1

BY_ISS_ID	= 0
BY_ISS_NAME = 1
BY_PUB_ID	= 2
BY_PUB_NAME = 3

# Menu bar items
ID_SORTBY		= 101
ID_FINDBY		= 102
ID_FINDBY_TEXT	= 103

ID_DISCONNECT		= 105
ID_RELOAD			= 106

ID_PUB_CREATE		= 111
ID_PUB_EDIT			= 112
ID_PUB_DELETE		= 113
ID_PUB_NEW_ISS		= 114
ID_PUB_CLONE		= 115
ID_PUB_COPY			= 116
ID_PUB_INSPECT		= 117

ID_ISS_EDIT			= 121
ID_ISS_DELETE		= 122
ID_ISS_PUBLISH		= 123
ID_ISS_CLONE		= 124
ID_ISS_COPY			= 125
ID_ISS_INSPECT		= 126


#
class newsletter_tree( wx.gizmos.TreeListCtrl ):
	def __init__( self, parent, id=-1 , style=0 ):
		wx.gizmos.TreeListCtrl.__init__( self, parent, id , style=style)
		self.sortby = BY_NAME
		self.ascending = 1
		if wx.Platform == '__WXMAC__':
			font = self.GetMainWindow().GetFont()
			font.SetPointSize( 10 )
			self.GetMainWindow().SetFont( font )
			font = self.GetHeaderWindow().GetFont()
			font.SetPointSize( 10 )
			self.GetHeaderWindow().SetFont( font )
		
	def OnCompareItems( self, item1, item2 ):
		t1 = self.GetPyData( item1 )
		t2 = self.GetPyData( item2 )
		if ( t1 is None ) or ( t2 is None ): return 0
		# Comparing issues,
		#~ if self.sortby == BY_STATUS:
			#~ # Active always goes on top
			#~ v1 = self.get_status_weight( t1["status"] )
			#~ v2 = self.get_status_weight( t2["status"] )
		if self.sortby == BY_NAME:
			v1 = t1["name"].lower()
			v2 = t2["name"].lower()
		elif self.sortby == BY_ID:
			v1 = int( t1["id"] )
			v2 = int( t2["id"] )
		if v1 < v2:  return ( -1 * self.ascending )
		if v1 == v2: return 0
		return ( 1 * self.ascending )

	def get_status_weight( self, status ):
		if status == "ACTIVATED": return 1
		if status == "DEACTIVATED": return 2
		if status == "ARCHIVED": return 3


class publication_control( wx.Panel ):
	def __init__( self, parent, id, account ):
		wx.Panel.__init__( self, parent, id )
		self.parent				= parent
		self.account			= account
		self.last_objects_found	= []
		# Create the menu bar
		self.create_menu_items()
		# Create the list control and set it's image list
		tID = wx.NewId()
		style = wx.TR_HAS_BUTTONS | wx.TR_NO_LINES | wx.TR_HIDE_ROOT | wx.TR_FULL_ROW_HIGHLIGHT
		if wx.Platform == '__WXMSW__':
			style = wx.TR_HAS_BUTTONS  | wx.TR_LINES_AT_ROOT | wx.TR_HIDE_ROOT | wx.TR_FULL_ROW_HIGHLIGHT
		self.tree = newsletter_tree( self, tID, style=style  )
		self.tree.AddColumn( "id" )
		self.tree.AddColumn( "name" )
		self.tree.SetMainColumn(0)
		self.il = wx.ImageList( 16,16 )
		self.folder_icon = 0
		new_folder_bitmap = None
		self.issue_icon = 0
		if self.__class__ == web_control:
			new_folder_bitmap = images.getNewFolderWBitmap()
			self.folder_icon = self.il.Add( images.getFolderWBitmap() )
			self.issue_icon = self.il.Add( images.getIssueWBitmap() )
		elif self.__class__ == newsletter_control:
			new_folder_bitmap = images.getNewFolderNBitmap()
			self.folder_icon = self.il.Add( images.getFolderNBitmap() )
			self.issue_icon = self.il.Add( images.getIssueNBitmap() )
		elif self.__class__ == email_control:
			new_folder_bitmap = images.getNewFolderEBitmap()
			self.folder_icon = self.il.Add( images.getFolderEBitmap() )
			self.issue_icon = self.il.Add( images.getIssueEBitmap() )
		self.tree.SetImageList( self.il )
		self.tree.SetColumnWidth( 0, 80 )
		self.tree.SetColumnWidth( 1, 400 )
		self.tree.GetMainWindow().Bind( wx.EVT_LEFT_DCLICK, self.OnItemDoubleClick )
		self.tree.GetMainWindow().Bind( wx.EVT_RIGHT_DOWN, self.OnTreeRightClick )
		self.tree.GetMainWindow().Bind( wx.EVT_LEFT_DOWN, self.OnTreeLeftClick )
		self.tree.GetHeaderWindow().Bind( wx.EVT_LEFT_DOWN, self.OnTreeHeaderLeftClick )
		self.tree.Bind( wx.EVT_TREE_SEL_CHANGED, self.OnTreeItemSelected)
		#if wx.Platform != '__WXMAC__':
		self.tree.Bind( wx.EVT_TREE_BEGIN_DRAG, self.OnBeginDrag, id=tID )
		self.topbar = wx.BoxSizer( wx.HORIZONTAL )
		# The new button
		self.new_button = wx.BitmapButton( self, -1, new_folder_bitmap, size=common.button_size, style=wx.NO_BORDER )
		self.new_button.Bind( wx.EVT_BUTTON, self.OnPublicationCreate )
		self.topbar.Add( self.new_button, 0 )
		# The script helper button
		self.sh_button = wx.BitmapButton( self, -1, images.getScriptHelperBitmap(), size=common.button_size, style=wx.NO_BORDER )
		self.sh_button.Bind( wx.EVT_BUTTON, self.OnShowScriptHelper )
		self.topbar.Add( self.sh_button, 0 )		
		# The refresh button
		self.refresh_button = wx.BitmapButton( self, -1, images.getRefreshBitmap(), size=common.button_size, style=wx.NO_BORDER )
		self.refresh_button.Bind( wx.EVT_BUTTON, self.reload_publications )
		self.topbar.Add( self.refresh_button, 0 )
		self.topbar.Add( (3,3), 0, wx.EXPAND )
		# The finding selector
		self.findby_choice = wx.Choice( self, ID_FINDBY, choices=self.find_choices )
		self.findby_choice.SetSelection( 0 )
		self.Bind( wx.EVT_CHOICE, self.OnFindByChange, id=ID_FINDBY )
		self.topbar.Add( self.findby_choice, 2, wx.EXPAND )
		self.find_by = 1	# Find by ID by default
		# The find text box
		self.find_text = wx.TextCtrl( self, ID_FINDBY_TEXT, "" )
		self.topbar.Add( self.find_text, 2, wx.EXPAND )
		self.Bind( wx.EVT_TEXT, self.OnFindByTextChange, id=ID_FINDBY_TEXT )
		self.find_text.Bind( wx.EVT_LEFT_DOWN, self.OnFindByTextClick )
		self.find_text.Bind( wx.EVT_KEY_DOWN, self.OnFindByTextKeyPress )
		# zoom button
		self.zoom_button = wx.BitmapButton( self, -1, images.getZoomBitmap(), size=common.button_size, style=wx.NO_BORDER )
		self.zoom_button.Bind( wx.EVT_BUTTON, self.OnZoom )
		self.topbar.Add( self.zoom_button, 0 )
		# The whole mess
		self.sizer = wx.BoxSizer( wx.VERTICAL )
		self.sizer.Add( self.topbar, 0, wx.EXPAND )
		self.sizer.Add( self.tree, 1, wx.EXPAND )
		self.SetSizer( self.sizer )
		self.SetAutoLayout( 1 )
		# Windows needs this call
		self.Layout()
		self.Show()
		self.publications = []
		self.reload_publications()
		
	def OnShowScriptHelper(self,event):
		self.account.window.account_manager.showScriptHelperWindow()

	def OnTreeItemSelected(self,event):
		common.dprint("OnTreeItemSelected Event ", event)
		treeitem = event.GetItem()
		if treeitem is None:
			common.dprint("OnTreeItemSelected No Treeitem")
			return
		obj = self.tree.GetPyData( treeitem )
		if obj is None:
			common.dprint("OnTreeItemSelected No Object")
			return
		if self.account.window.account_manager.inspectorWindow:
			self.account.window.account_manager.inspectorWindow.setObject(obj)

	def OnInspect(self,event):
		common.dprint("OnInspect Event ", event)
		item = self.tree.GetSelection()
		if item is None: return
		obj = self.tree.GetPyData( item )
		if obj is None: return
		self.account.window.account_manager.showInspectorWindow()
		self.account.window.account_manager.inspectorWindow.setObject(obj)
		
		
	def OnTreeHeaderLeftClick( self, event ):
		treeitem, thing, column_index = self.tree.HitTest( event.GetPositionTuple() )
		# flip the asc desc?
		if self.tree.sortby == column_index:
			self.tree.ascending = self.tree.ascending * -1
		self.tree.sortby = column_index
		self.tree.SortChildren( self.root )
		# sort the issues
		for pub in self.publications:
			self.tree.SortChildren( pub.tree_item )

	def OnBeginDrag( self, event ):
		item = self.tree.GetSelection()
		if item is None: return
		obj = self.tree.GetPyData( item )
		if obj is None: return
		data = wx.PyTextDataObject()
		if  obj.object_name == "publication":
			xmlstring = obj.toxml()
			data.SetText( xmlstring )
		elif obj.object_name == "issue":
			linktag = "<#[" + self.issue_url_tag + obj["id"] + "]#>"
			data.SetText( linktag )
		else:
			return
		ds = wx.DropSource( self )
		ds.SetData( data )
		result = ds.DoDragDrop()

	def create_menu_items( self ):
		self.menubar = self.account.window.menubar

	def OnZoom( self, event ):
		if self.account.window: self.account.window.OnZoom( 2 )

	def AppendPublication( self, pub ):
		pub_item = self.tree.AppendItem( self.root, pub["id"] )
		self.tree.SetItemText( pub_item, pub["name"], 1 )
		self.tree.SetItemImage( pub_item, self.folder_icon )
		self.tree.SetItemBold( pub_item, 1 )
		# Now, cross link
		self.tree.SetPyData( pub_item, pub )
		return pub_item

	def AppendIssue( self, pub_item, iss ):
		iss_item = self.tree.AppendItem( pub_item, iss["id"] )
		self.tree.SetItemText( iss_item, iss["name"], 1 )
		self.tree.SetItemImage( iss_item, self.issue_icon )
		# Colorize
		if iss["status"] == "deactivated":
			bgcolor="#F5F5FF"
			color = "#5555EE"
		elif iss["status"] == "archived":
			bgcolor="#F5F5F5"
			color = "#666666"
		else:
			bgcolor="#FFF7F7"
			color = "#FF5555"
		self.tree.SetItemTextColour( iss_item, color )
		self.tree.SetItemBackgroundColour( iss_item, bgcolor )
		# Now, cross link
		self.tree.SetPyData( iss_item, iss )
		return iss_item

	def reload_publications( self, event=None ):
		# Close off all open child frames
		#if not self.CloseAllFrames(): return
		module = ''
		if self.__class__ is web_control:
			module = 'Web'
		elif self.__class__ is newsletter_control:
			module = 'Newsletter'
		elif self.__class__ is email_control:
			module = 'Email'
		else:
			common.show_error("Failed to determine the module")
			return
		if self.account.window: self.account.window.SetStatusText( "Getting %ss..." % ( self.parent_object_name.lower() ) )
		wx.Yield()
		# Clear out the current tree
		self.publications = []
		self.tree.DeleteAllItems()
		# Add the root
		self.root = self.tree.AddRoot( self.parent_object_name.capitalize() + "s" )
		# Get the publications
		pubs = None
		try:
			cur = wx.BusyCursor()
			xmlstring = self.account.execute( module, "publications_get2")
			xmlstring = common.uni2str( xmlstring )
			pdom 	= minidom.parseString( xmlstring )
			pubs	= pdom.firstChild
		except:
			common.show_error("Failed to load publications")
		del cur
		if not pubs: return
		for pnode in pubs.getElementsByTagName("publication"):
			pub = rex.publications.publication( self.account, module, common.uni2str( pnode.toxml() ) )
			self.publications.append( pub )
			# Create a tree node for the publication object and it's children
			pub_item = self.AppendPublication( pub )
			pub.tree_item = pub_item
			# How about it's issues?
			for iss in pub.issues:
				iss_item = self.AppendIssue( pub_item, iss )
				iss.tree_item = iss_item
			self.tree.SortChildren( pub_item )
		self.tree.SortChildren( self.root )
		if self.account.window: self.account.window.SetStatusText( "Ready" )
		self.tree.Refresh()
		
	def updatePubName( self, id ):
		self.tree.SetItemText( pub_item, pub["name"], 1 )
		return
	
	def updateIssName( self, id ):
		self.tree.SetItemText( iss_item, iss["name"], 1 )
		return

	def OnFindByChange( self, event ):
		selected = self.findby_choice.GetSelection()
		if selected < 0: return
		if self.root is None: return
		if self.tree.GetChildrenCount( self.root ) < 1: return
		self.find_text.SetValue("")
		self.find_text.SetFocus()

	def OnFindByTextClick( self, event ):
		length = len( self.find_text.GetValue() )
		if length > 0:
			self.find_text.SetSelection( 0, length )
		event.Skip()

	def OnFindByTextKeyPress( self, event ):
		if event.GetKeyCode() == wx.WXK_RETURN:
			self.OnFindByTextChange( event, True )
			return
		event.Skip()

	def OnFindByTextChange( self, event=None,FindNext= False ):
		if not FindNext: self.last_objects_found = []
		selected = self.findby_choice.GetSelection()
		search_text = self.find_text.GetValue()
		if len( search_text.strip() ) < 1:
			self.tree.UnselectAll()
			return
		# If we are looking for an ID, strip the id entered
		search_text = search_text.strip().replace("\\","\\\\")
		found_something = 0
		if ( selected == 0 ) or ( selected == 2 ):
			prop = "id"
		else:
			prop = "name"
		object = None

		# Create the matcher text
		search_pattern = re.compile( "^%s" % search_text, re.I )
		for pub in self.publications:
			if selected > 1:
				# Match the string in the publication property
				if re.search( search_pattern, pub[ prop ] ) is not None:
					if FindNext and ( pub in self.last_objects_found ): continue
					object = pub
					break
			else:
				# We are doing issues
				for iss in pub.issues:
					# Match the string in the issue property
					if re.search( search_pattern, iss[ prop ] ) is not None:
						if FindNext and ( iss in self.last_objects_found ): continue
						object = iss
						break

		# If we found nothing, clear the selection, otherwise, select it
		if object is None:
			self.tree.UnselectAll()
			self.last_objects_found = []
		else:
			self.tree.EnsureVisible( object.tree_item )
			self.tree.SelectItem( object.tree_item )
			self.last_objects_found.append( object )
		self.tree.Refresh()

	def OnClose( self, event ):
		'''When closing the service frame, the account manager icon is updated and the
		service reference is cleared out.
		If the account manager's disconnect_account method returns a false, the closing is
		not performed.'''
		# Close off all child frames
		if not self.CloseAllFrames(): return
		# Decrement the binder sui ref count
		da = self.GetParent().disconnect_account
		if da( self.account.account_manager_aid ) == 1:
			bf = self.account.binder_frame
			bf.ref_count = bf.ref_count -1
			bf.Close()
			cf = self.account.contact_frame
			cf.ref_count = cf.ref_count -1
			cf.Close()
			event.Skip()
			return True
		return False

	def OnDisconnect( self, event ):
		if self.OnClose( event ):
			self.Destroy()


	def OnPublicationCreate( self, event ):
		module = ''
		if self.__class__ is web_control:
			module = 'Web'
		elif self.__class__ is newsletter_control:
			module = 'Newsletter'
		elif self.__class__ is email_control:
			module = 'Email'
		else:
			common.show_error("Failed to determine the module")
			return
		pub = rex.publications.publication( self.account, module, None )
		# Create the new publication on the server, that will give it an ID
		pub["public"] = "0"
		pub["layout"] = "NL"
		new_name = "New %s" % self.parent_object_name.capitalize()
		pub.create( new_name )
		self.publications.append( pub )
		# Create a tree node for the publication object and it's children
		pub_item = self.AppendPublication( pub )
		pub.tree_item = pub_item
		self.tree.SelectItem( pub_item )
		self.OnItemDoubleClick( None )

	def OnPublicationClone( self, event ):
		item = self.tree.GetSelection()
		if item is None: return
		pub = self.tree.GetPyData( item )
		if pub is None: return
		if pub.object_name != "publication": return
		# Create the new publication on the server, that will give it an ID
		new_pid = pub.clone()
		self.reload_publications()

	def OnPublicationCopy( self, event ):
		item = self.tree.GetSelection()
		if item is None: return
		pub = self.tree.GetPyData( item )
		if pub is None: return
		if pub.object_name != "publication": return
		obj = pub.toxml()
		# Now let's put it in the clipboard
		clipdata = wx.TextDataObject()
		clipdata.SetText( obj )
		wx.TheClipboard.Open()
		wx.TheClipboard.SetData( clipdata )
		wx.TheClipboard.Close()

	def OnPublicationDelete( self, event ):
		item = self.tree.GetSelection()
		if item is None: return
		pub = self.tree.GetPyData( item )
		if pub is None: return
		if pub.object_name != "publication": return
		# Confirm delete
		dconf = "Are you sure you want to delete this %s and all it's %ss?" % \
				( self.parent_object_name.capitalize(), self.child_object_name.capitalize() )
		res = wx.MessageBox( dconf, "Confirm Delete", wx.YES_NO )
		if res != wx.YES: return
		if pub.delete():
			if pub.editor is not None:
				self.account.window.ebook.RemovePage( common.get_page_index( self.account.window.ebook, pub.editor ) )
				#pub.editor.Destroy()
			for iss in pub.issues:
				if iss.editor is not None:
					self.account.window.ebook.RemovePage( common.get_page_index( self.account.window.ebook, iss.editor ) )
					#iss.editor.Destroy()
			self.publications.remove( pub )
			self.tree.Delete( item )
			pub = None

	def OnPublicationNewIssue( self, event ):
		item = self.tree.GetSelection()
		if item is None: return
		pub = self.tree.GetPyData( item )
		if pub is None: return
		if pub.object_name != "publication":
			# This is really an issue, lets get the publication from it
			if pub.object_name != "issue": return
			pub  = pub.publication
			item = pub.tree_item

		iss = rex.publications.issue( self.account, pub, None )
		# Create the new issue on the server, that will give it an ID
		iss["publication_id"] = pub["id"]
		new_name = "New %s" % self.child_object_name.capitalize()
		iss.create( new_name )
		iss['name'] = new_name
		pub.issues.append( iss )
		iss_item = self.AppendIssue( item, iss )
		iss.tree_item = iss_item
		self.tree.Expand( item )
		self.tree.SelectItem( iss_item )
		self.OnItemDoubleClick( None )

	def OnIssueClone( self, event ):
		item = self.tree.GetSelection()
		if item is None: return
		iss = self.tree.GetPyData( item )
		if iss is None: return
		if iss.object_name != "issue": return
		pub = iss.publication
		# Create the new issue on the server, that will give it an ID
		new_iid = iss.clone()
		if len( new_iid.strip() ) < 1: return
		new_iss = rex.publications.issue( self.account, pub, None )
		new_iss["id"] = new_iid
		new_iss["name"] = "Cloned %s" % iss["name"]
		new_iss["publication_id"] = pub["id"]
		new_iss["status"] = iss["status"]
		new_iss.publication = pub
		pub.issues.append( new_iss )
		iss_item = self.AppendIssue( pub.tree_item, new_iss )
		new_iss.tree_item = iss_item
		self.tree.Expand( item )
		self.tree.SelectItem( iss_item )
		self.OnItemDoubleClick( None )

	def OnIssueCopy( self, event ):
		item = self.tree.GetSelection()
		if item is None: return
		iss = self.tree.GetPyData( item )
		if iss is None: return
		if iss.object_name != "issue": return
		obj = "<#[PAGE_URL_%s]#>" % (iss['id'],  )
		# Now let's put it in the clipboard
		clipdata = wx.TextDataObject()
		clipdata.SetText( obj )
		wx.TheClipboard.Open()
		wx.TheClipboard.SetData( clipdata )
		wx.TheClipboard.Close()

	def OnIssueDelete( self, event ):
		item = self.tree.GetSelection()
		if item is None: return
		iss = self.tree.GetPyData( item )
		if iss is None: return
		if iss.object_name != "issue": return
		# Confirm delete
		dconf = "Are you sure you want to delete this %s?" % self.child_object_name.capitalize()
		res = wx.MessageBox( dconf, "Confirm Delete", wx.YES_NO )
		if res != wx.YES: return
		if iss.delete():
			if iss.editor is not None:
				self.account.window.ebook.RemovePage( common.get_page_index( self.account.window.ebook, iss.editor ) )
				#iss.editor.Destroy()
			self.tree.Delete( item )
			iss = None

	def OnIssuePublish( self, event ):
		item = self.tree.GetSelection()
		if item is None: return
		iss = self.tree.GetPyData( item )
		if iss is None: return
		if iss.object_name != "issue": return
		dlg = publications.publisher( self, self.account, iss )
		dlg.Show()

	def OnTreeLeftClick( self, event ):
		self.tree.Refresh()
		event.Skip()

	def OnTreeRightClick( self, event ):
		item, where, column = self.tree.HitTest( event.GetPosition() )
		if item is None: return
		object = None
		try: object = self.tree.GetPyData( item )
		except: pass
		if object is None:
			self.PopupMenu( self.none_menu, wx.Point( event.m_x + 5, event.m_y + 15) )
			return
		menu = None
		if object.object_name == "publication":
			menu = self.pub_menu
		elif object.object_name == "issue":
			menu = self.iss_menu
		if menu is None: return
		self.tree.EnsureVisible( item )
		self.tree.SelectItem( item )
		self.PopupMenu( menu, wx.Point( event.m_x + 5, event.m_y + 15) )

	def OnItemDoubleClick( self, event ):
		item = self.tree.GetSelection()
		if item is None: return
		rexObject = self.tree.GetPyData( item )
		if rexObject is None: return
		module = ''
		if self.__class__ is web_control:
			module = 'web'
		elif self.__class__ is newsletter_control:
			module = 'news'
		elif self.__class__ is email_control:
			module = 'mail'
		else:
			common.show_error("Failed to determine the module")
			return
		if rexObject.object_name == "publication":
			# Inspect instead of opening header
			self.OnInspect(event)
			#pb=("pubs-%s" % module, rexObject['id'],"header.espx")
			#self.account.coordinator.addFileSet(pb)
			#self.account.coordinator.openFile(pb)
		elif rexObject.object_name == "issue":
			pb=("issues-%s" % module, rexObject['id'],"content.espx")
			self.account.coordinator.addFileSet(pb)
			self.account.coordinator.openFile(pb)

	def SetTextOfItem( self, item, text ):
		self.tree.SetItemText( item, text )

	def CloseAllFrames( self ):
		'''Cycle through all publications and issues and close off their frames if any.'''
		for p in self.publications:
			if p.editor is not None:
				f = p.editor
				if f.OnClose( None ):
					f.Destroy()
				else:
					return False
			# Check it's child publications
			for i in p.issues:
				if i.editor is not None:
					f = i.editor
					if f.OnClose( None ):
						f.Destroy()
					else:
						return False
		return True

####################################################################################################
class newsletter_control( publication_control ):
	def __init__( self, parent, id, account ):
		self.find_choices 		= ["Issue ID", "Issue Name","Publication ID", "Publication Name"]
		self.issue_url_tag		= "ISSUE_URL_"
		self.child_object_name 	= "Issue"
		self.parent_object_name	= "Publication"
		self.icon_name			= "NewsletterModule"
		publication_control.__init__( self, parent, id, account )

	def create_menu_items( self ):
		publication_control.create_menu_items( self )
		# The nothing menu
		menu = wx.Menu()
		menu.Append( ID_RELOAD, "&Reload\tCtrl+R", " Reload" )
		menu.AppendSeparator()
		menu.Append( ID_PUB_CREATE, "&Create a New Publication", " Create a new publication" )
		self.none_menu = menu
		# The publication menu
		menu = wx.Menu()
		menu.Append( ID_RELOAD, "&Reload\tCtrl+R", " Reload" )
		self.Bind( wx.EVT_MENU, self.reload_publications, id=ID_RELOAD )
		menu.AppendSeparator()
		menu.Append( ID_PUB_CREATE, "&Create a New Publication", " Create a new publication" )
		menu.Append( ID_PUB_CLONE, "&Clone", " Clone the selected publication" )
		menu.AppendSeparator()
		menu.Append( ID_PUB_COPY, "&Copy", " Copy the selected publication to the clipboard" )
#		menu.Append( ID_PUB_EDIT, "&Edit", " Edit the selected publication" )
		menu.Append( ID_PUB_DELETE, "&Delete", " Delete the selected publication" )
		menu.Append( ID_PUB_INSPECT, "&Inspect Publication", " Inspect the selected publication" )
		menu.AppendSeparator()
		menu.Append( ID_PUB_NEW_ISS, "&Add New Issue", " Create a new issue in the selected publication" )
		self.pub_menu = menu
		self.Bind( wx.EVT_MENU, self.OnPublicationCreate	, id=ID_PUB_CREATE )
		self.Bind( wx.EVT_MENU, self.OnPublicationClone		, id=ID_PUB_CLONE )
		self.Bind( wx.EVT_MENU, self.OnPublicationCopy		, id=ID_PUB_COPY )
		self.Bind( wx.EVT_MENU, self.OnItemDoubleClick		, id=ID_PUB_EDIT	)
		self.Bind( wx.EVT_MENU, self.OnPublicationDelete	, id=ID_PUB_DELETE )
		self.Bind( wx.EVT_MENU, self.OnPublicationNewIssue	, id=ID_PUB_NEW_ISS )
		self.Bind( wx.EVT_MENU, self.OnInspect				, id=ID_PUB_INSPECT )
		#self.menubar.Append( menu, "&Publications" )
		# The issue menu
		menu = wx.Menu()
		menu.Append( ID_PUB_NEW_ISS, "&Create a New Issue", " Create a new issue in the selected publication" )
		menu.Append( ID_ISS_CLONE, "&Clone", " Clone the selected issue" )
		menu.AppendSeparator()
		menu.Append( ID_ISS_COPY, "&Copy", " Copy the selected issue to the clipboard" )
		menu.Append( ID_ISS_EDIT, "&Edit", " Edit the selected issue" )
		menu.Append( ID_ISS_DELETE, "&Delete", " Delete the selected issue" )
		menu.Append( ID_ISS_PUBLISH, "&Publish", " Publish the selected issue" )
		menu.Append( ID_ISS_INSPECT, "&Inspect Issue", " Inspect the selected issue" )
		self.Bind( wx.EVT_MENU, self.OnIssueCopy, id=ID_ISS_COPY )
		self.Bind( wx.EVT_MENU, self.OnIssueClone, id=ID_ISS_CLONE )
		self.Bind( wx.EVT_MENU, self.OnItemDoubleClick, id=ID_ISS_EDIT )
		self.Bind( wx.EVT_MENU, self.OnIssueDelete, id= ID_ISS_DELETE )
		self.Bind( wx.EVT_MENU, self.OnIssuePublish, id=ID_ISS_PUBLISH )
		self.Bind( wx.EVT_MENU, self.OnInspect	, id=ID_ISS_INSPECT )
		self.iss_menu = menu
		#self.menubar.Append( menu, "&Issue" )

class email_control( publication_control ):
	def __init__( self, parent, id, account ):
		self.find_choices 		= ["Email ID", "Email Name","Campaign ID", "Campaign Name"]
		self.issue_url_tag		= "EMAIL_URL_"
		self.child_object_name 	= "Email"
		self.parent_object_name	= "Campaign"
		self.icon_name			= "EmailModule"
		publication_control.__init__( self, parent, id, account )

	def create_menu_items( self ):
		publication_control.create_menu_items( self )
		# The nothing menu
		menu = wx.Menu()
		menu.Append( ID_RELOAD, "&Reload\tCtrl+R", " Reload" )
		menu.AppendSeparator()
		menu.Append( ID_PUB_CREATE, "&Create a New Campaign", " Create a new campaign" )
		self.none_menu = menu
		# The publication menu
		menu = wx.Menu()
		menu.Append( ID_RELOAD, "&Reload\tCtrl+R", " Reload" )
		self.Bind( wx.EVT_MENU, self.reload_publications, id=ID_RELOAD )
		menu.AppendSeparator()
		menu.Append( ID_PUB_CREATE, "&Create a New Campaign", " Create a new campaign" )
		menu.Append( ID_PUB_CLONE, "&Clone", " Clone the selected campaign" )
		menu.AppendSeparator()
		menu.Append( ID_PUB_COPY, "&Copy", " Copy the selected campaign to the clipboard" )
#		menu.Append( ID_PUB_EDIT, "&Edit", " Edit the selected campaign" )
		menu.Append( ID_PUB_DELETE, "&Delete", " Delete the selected campaign" )
		menu.Append( ID_PUB_INSPECT, "&Inspect Campaign", " Inspect the selected campaign" )
		menu.AppendSeparator()
		menu.Append( ID_PUB_NEW_ISS, "&Add New Email", " Create a new email in the selected campaign" )
		self.pub_menu = menu
		self.Bind( wx.EVT_MENU, self.OnPublicationCreate, id=ID_PUB_CREATE )
		self.Bind( wx.EVT_MENU, self.OnPublicationClone, id=ID_PUB_CLONE )
		self.Bind( wx.EVT_MENU, self.OnItemDoubleClick, id=ID_PUB_EDIT )
		self.Bind( wx.EVT_MENU, self.OnPublicationCopy		, id=ID_PUB_COPY )
		self.Bind( wx.EVT_MENU, self.OnPublicationDelete, id=ID_PUB_DELETE )
		self.Bind( wx.EVT_MENU, self.OnPublicationNewIssue, id=ID_PUB_NEW_ISS )
		self.Bind( wx.EVT_MENU, self.OnInspect				, id=ID_PUB_INSPECT )
		#self.menubar.Append( menu, "&Campaign" )
		# The issue menu
		menu = wx.Menu()
		menu.Append( ID_PUB_NEW_ISS, "&Create a New Email", " Create a new email in the selected campaign" )
		menu.Append( ID_ISS_CLONE, "&Clone", " Clone the selected email" )
		menu.AppendSeparator()
		menu.Append( ID_ISS_COPY, "&Copy", " Copy the selected email to the clipboard" )
		menu.Append( ID_ISS_EDIT, "&Edit", " Edit the selected email" )
		menu.Append( ID_ISS_DELETE, "&Delete", " Delete the selected email" )
		menu.Append( ID_ISS_PUBLISH, "&Publish", " Publish the selected email" )
		menu.Append( ID_ISS_INSPECT, "&Inspect Email", " Inspect the selected email" )
		self.Bind( wx.EVT_MENU, self.OnIssueCopy, id=ID_ISS_COPY )
		self.Bind( wx.EVT_MENU, self.OnItemDoubleClick, id=ID_ISS_EDIT )
		self.Bind( wx.EVT_MENU, self.OnIssueClone, id=ID_ISS_CLONE )
		self.Bind( wx.EVT_MENU, self.OnIssueDelete, id=ID_ISS_DELETE)
		self.Bind( wx.EVT_MENU, self.OnIssuePublish, id=ID_ISS_PUBLISH )
		self.Bind( wx.EVT_MENU, self.OnInspect, id=ID_ISS_INSPECT )
		self.iss_menu = menu
		#self.menubar.Append( menu, "&Email" )

class web_control( publication_control ):
	def __init__( self, parent, id, account ):
		self.find_choices 		= ["Page ID", "Page Name","Web Folder ID", "Web Folder Name"]
		self.issue_url_tag		= "PAGE_URL_"
		self.child_object_name 	= "Page"
		self.parent_object_name	= "Web Folder"
		self.icon_name			= "WebModule"
		publication_control.__init__( self, parent, id, account )

	def create_menu_items( self ):
		publication_control.create_menu_items( self )
		# The nothing menu
		menu = wx.Menu()
		menu.Append( ID_RELOAD, "&Reload\tCtrl+R", " Reload" )
		menu.AppendSeparator()
		menu.Append( ID_PUB_CREATE, "&Create a New Folder", " Create a new folder" )
		self.none_menu = menu
		# The publication menu
		menu = wx.Menu()
		menu.Append( ID_RELOAD, "&Reload\tCtrl+R", " Reload" )
		self.Bind( wx.EVT_MENU, self.reload_publications, id=ID_RELOAD )
		menu.AppendSeparator()
		menu.Append( ID_PUB_CREATE, "&Create a New Web Folder", " Create a new web folder" )
		menu.Append( ID_PUB_CLONE, "&Clone", " Clone the selected web folder" )
		menu.AppendSeparator()
		menu.Append( ID_PUB_COPY, "&Copy", " Copy the selected web folder to the clipboard" )
#		menu.Append( ID_PUB_EDIT, "&Edit", " Edit the selected web folder" )
		menu.Append( ID_PUB_DELETE, "&Delete", " Delete the selected web folder" )
		menu.Append( ID_PUB_INSPECT, "&Inspect Folder", " Inspect the selected folder" )
		menu.AppendSeparator()
		menu.Append( ID_PUB_NEW_ISS, "&Add New Page", " Create a new page in the selected web folder" )
		self.pub_menu = menu
		self.Bind( wx.EVT_MENU, self.OnPublicationCreate, id=ID_PUB_CREATE	 )
		self.Bind( wx.EVT_MENU, self.OnPublicationClone,  id=ID_PUB_CLONE	)
		self.Bind( wx.EVT_MENU, self.OnItemDoubleClick,	  id=ID_PUB_EDIT )
		self.Bind( wx.EVT_MENU, self.OnPublicationCopy	, id=ID_PUB_COPY )
		self.Bind( wx.EVT_MENU, self.OnPublicationDelete, id=ID_PUB_DELETE	 )
		self.Bind( wx.EVT_MENU, self.OnPublicationNewIssue, id=ID_PUB_NEW_ISS )
		self.Bind( wx.EVT_MENU, self.OnInspect				, id=ID_PUB_INSPECT )
		#self.menubar.Append( menu, "&Web Folder" )
		# The issue menu
		menu = wx.Menu()
		menu.Append( ID_PUB_NEW_ISS, "&Create New", " Create a new page in the selected web folder" )
		menu.Append( ID_ISS_CLONE, "&Clone", " Clone the selected page" )
		menu.AppendSeparator()
		menu.Append( ID_ISS_COPY, "&Copy", " Copy the selected pag to the clipboard" )
		menu.Append( ID_ISS_EDIT, "&Edit", " Edit the selected page" )
		menu.Append( ID_ISS_DELETE, "&Delete", " Delete the selected page" )
		menu.Append( ID_ISS_INSPECT, "&Inspect Page", " Inspect the selected page" )
		self.Bind( wx.EVT_MENU, self.OnIssueCopy, id=ID_ISS_COPY )
		self.Bind( wx.EVT_MENU, self.OnIssueClone, id=ID_ISS_CLONE )
		self.Bind( wx.EVT_MENU, self.OnItemDoubleClick, id=ID_ISS_EDIT )
		self.Bind( wx.EVT_MENU, self.OnIssueDelete, id=ID_ISS_DELETE )
		self.Bind( wx.EVT_MENU, self.OnInspect, id=ID_ISS_INSPECT )
		self.iss_menu = menu
		#self.menubar.Append( menu, "&Page" )
